🟪 Today’s data: Naver News Search Results

Naver Open API

We are not using .csv file toady.

🟪 API and XML 🟪

API (Application Programming Interface): Mechanism or system enabling two software components to communicate using a set of definitions and protocols. (https://aws.amazon.com/what-is/api/ https://brunch.co.kr/@jhw28/31)

Let’s look at the address of CAU Notice page.

We are using NAVER Open API today. To use an API, you have to read the API reference. It’s sort of a dictionary.

https://developers.naver.com/docs/serviceapi/search/news/news.md#%EB%89%B4%EC%8A%A4

XML (Extensible Markup Language): Language used to define and store data in a sharable manner. ( https://aws.amazon.com/what-is/xml/?nc1=h_ls, https://www.tcpschool.com/xml/xml_basic_structure)


library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(httr)
library(XML)

Select your word to search.

keyword <- "검색하고싶으은문자열을넣으세요"

Using API, we need to communicate with NAVER the But, URL doesnt not understand 한글. Just like the NAVER API reference document address above, it should be in Percent Encoding. “%” sign does not mean percentage. https://www.youtube.com/watch?v=3DNaj8R4HJg&t=37s

(https://it-eldorado.tistory.com/143, https://bunny.net/academy/http/what-is-url-uniform-resource-identifier-and-percent-encoding/)

myQuery <- keyword %>%
    enc2utf8() %>%
    URLencode()

print(myQuery)
## [1] "%EC%97%AC%ED%96%89"

We are making an order to API server. 1) language: percent encoding. 2) vocabulary: read the reference.

searchUrl <- "https://openapi.naver.com/v1/search/news.xml"

chunk <- 50
startNumber <-1
sort<- "sim"

url <- glue::glue("{searchUrl}?query={myQuery}&display={chunk}&start={startNumber}&sort={sort}")
url
## https://openapi.naver.com/v1/search/news.xml?query=%EC%97%AC%ED%96%89&display=50&start=1&sort=sim

GET(url, add_header(information to request) : retrieves the page with the url

doc_raw <- url %>%
    GET(
      add_headers(
        "X-Naver-Client-Id"     = client_id,
        "X-Naver-Client-Secret" = client_secret
      )
    ) %>%
    toString() %>%
    XML::xmlParse()

Let’s see how doc_raw looks like.

It’s well organized but hard to read. Let’s make it into a dataframe. One row for one article.

doc_df<- doc_raw %>%
  getNodeSet("//item") %>%
  xmlToDataFrame()

head(doc_df)

As NAVER News search result shows my keyword in bold, the reuslt also has <b></b> html tags. We really do not neet it. Let’s remove it.

For that, we are using regular expression, which is also a way of present letters/numbers/punctuation and stuff.

https://regex101.com/

https://www.youtube.com/shorts/kGFUu5WAzd8

library(stringr)
doc_df%>%mutate(title_text = str_remove_all(
      title, "&\\w+;|<[[:punct:]]*b>"))

Similarly, let’s define a function to refine the texts.

get_list <- function(doc) {
  refined<- doc %>%
    getNodeSet("//item") %>%
    xmlToDataFrame() %>%
    rename("publish_date" = pubDate) %>%
    mutate(publish_date = as.POSIXct(publish_date,
                                     format = "%a, %d %b %Y %H:%M:%S %z")) %>%
    mutate(title_text = str_replace_all(
      title, "&\\w+;|<[[:punct:]]*b>", " ")) %>%
    mutate(title_text = str_replace_all(
      title_text, "([[:punct:]])", " ")) %>%
    mutate(title_text = str_replace_all(
      title_text, "\\s{2,}", " ")) %>%
    mutate(title_text = str_remove_all(
      title_text, "\\A\\s+")) %>%
    mutate(description_text = str_remove_all(
      description,
      "&\\w+;|<[[:punct:]]*b>|[“”]"))
  return(refined)
}
get_list(doc_raw)

Let’s say we want to get 100 result for “첫눈” and 500 results for “채용”. What do we do when repeating same process? Use a function :)

NNSearch <- function(keyword = NULL, chunk = 100, start = 1,
                         sort = c("date", "sim"), do_done = FALSE, max = 1000L, 
                         client_id = client_id, client_secret = client_secret, 
                         verbose = TRUE) {
  if (is.null(keyword)) {
    stop("Error: Input search keyword")
  }
  
  if (chunk < 1 & chunk > 100) {
    stop("Error: Chunk size should be 1 < chunk <=100")
  }
  
  if (start < 1 & start > 1000) {
    stop("Error: Start should be 1< start <=1000.")
  }
  
  sort <- match.arg(sort)

  
  searchUrl <- "https://openapi.naver.com/v1/search/news.xml"
  
  query <- keyword %>%
    enc2utf8() %>%
    URLencode()
  
  url <- glue::glue("{searchUrl}?query={query}&display={chunk}&start={start}&sort={sort}")
  
  doc <- url %>%
    GET(
      add_headers(
        "X-Naver-Client-Id"     = client_id,
        "X-Naver-Client-Secret" = client_secret
      )
    ) %>%
    toString() %>%
    XML::xmlParse()
  
  totalNaverResult <- doc %>%
    XML::getNodeSet("//total") %>%
    XML::xmlValue() %>%
    as.integer()
  
  if (!do_done){
    max <- chunk
  }
  
  if (verbose) {
    glue::glue("* [{keyword}] 뉴스 검색 결과: 총 {totalNaverResult}건.\n\n") %>%
      cat()
    
    glue::glue("  - ({chunk}/{min(totalNaverResult, max)})건 완료.\n\n") %>%
      cat()
  }
  
  search_list <- doc %>%
    get_list()
  
  nRecord <- NROW(search_list)
  
  if (!do_done | nRecord >= totalNaverResult | nRecord >= max) {
    return(search_list)
  } else {
    totalMyResult <- min(totalNaverResult, max)
    
    pageCount <- totalMyResult %/% chunk
    if (totalMyResult %/% chunk == 0) {
      pageCount <- pageCount - 1
    }
    
    idx <- (seq(pageCount-1)+1)
    
    add_list <- idx[idx <= 1000] %>%
      purrr::map_df({
        function(x) {
          if (verbose) {
            glue::glue("  - ({chunk * x}/{totalMyResult})건 .\n\n") %>%
              cat()
          }
          
          glue::glue(
            "{searchUrl}?query={query}&display={chunk}&start={x}&sort={sort}"
          ) %>%
            httr::GET(
              httr::add_headers(
                "X-Naver-Client-Id"     = client_id,
                "X-Naver-Client-Secret" = client_secret
              )
            ) %>%
            toString() %>%
            XML::xmlParse() %>%
            get_list()
        }
      })
    
    search_list %>%
      bind_rows(
        add_list
      ) %>%
      return()
  }
}
firstsnow<- NNSearch("첫눈", client_id = client_id, client_secret = client_secret,
                     sort="sim", max=100, do_done=T)
## * [첫눈] 뉴스 검색 결과: 총 120463건.
## - (100/100)건 완료.
hiring_sim<- NNSearch("채용", client_id = client_id, client_secret = client_secret,
                     sort="sim", max=1000, do_done=T)
## * [채용] 뉴스 검색 결과: 총 2730527건.
## - (100/1000)건 완료.
## - (200/1000)건 .
## - (300/1000)건 .
## - (400/1000)건 .
## - (500/1000)건 .
## - (600/1000)건 .
## - (700/1000)건 .
## - (800/1000)건 .
## - (900/1000)건 .
## - (1000/1000)건 .
hiring_date<- NNSearch("채용", client_id = client_id, client_secret = client_secret,
                     sort="date", max=1000, do_done=T)
## * [채용] 뉴스 검색 결과: 총 2730527건.
## - (100/1000)건 완료.
## - (200/1000)건 .
## - (300/1000)건 .
## - (400/1000)건 .
## - (500/1000)건 .
## - (600/1000)건 .
## - (700/1000)건 .
## - (800/1000)건 .
## - (900/1000)건 .
## - (1000/1000)건 .

library(tm) 
## Loading required package: NLP
## 
## Attaching package: 'NLP'
## The following object is masked from 'package:httr':
## 
##     content
#devtools::install_github('haven-jeon/KoNLP')
library(KoNLP)
## Checking user defined dictionary!
useSejongDic()
## Backup was just finished!
## 370957 words dictionary was built.

Noun extraction

sentence<- "과일 비싸다고 안 사 먹으면 죽어서 제사상에서나 먹겠지. 인생 별거 있나 나에게 남은 여름은 100번도 안 된다."
extractNoun(sentence)
## [1] "과일"   "제사상" "인생"   "별거"   "나"     "남"     "여름"   "100"   
## [9] "번"

break down by morpheme

tidytext::unnest_tokens(dataframe, new column, source column, criteria) break down text data by token (vowel / consonant / letter / morpheme / word / n-gram /..)

#install.packages("tidytext")
library(tidytext)
hiring_date_word<- hiring_date %>% 
  unnest_tokens(title_word, title_text, "words")
hiring_date_word
hiring_date_pos <-hiring_date%>% unnest_tokens(pos, title_text, SimplePos09) %>%
  group_by(originallink) %>%
  mutate(pos_order = 1:n())
hiring_date_pos

Let’s take nouns only.

hiring_date_pos2<- hiring_date_pos %>%
  filter(str_detect(pos, "/n")) %>%
  mutate(pos_done = str_remove(pos, "/n.*$")) %>%
  mutate(pos_done = str_remove(pos_done, ".*\\+(?=.)"))
hiring_date_pos2
hiring_date_pos2$pos_done%>%table%>%sort(decreasing=T)
## .
##                   모                 연속                   집 
##                  202                  144                  143 
##         지역사회공헌               인정제               코레일 
##                  137                  134                  127 
##                  2년             최고등급           티웨이항공 
##                  124                  107                   79 
##               멘토링                   공             추진단장 
##                   75                   69                   69 
##                 올해                  5기           객실승무원 
##                   61                   60                   60 
##           에이블스쿨                   용                   채 
##                   60                   59                   59 
##             프로젝트               한국형                   개 
##                   59                   59                   52 
##                 채용                   최                   운 
##                   52                   52                   50 
##                   데                 동문               중앙대 
##                   48                   48                   48 
##                 현직             프로그램                  2기 
##                   48                   47                   43 
##               대학생             브루킨즈             싱크탱크 
##                   43                   43                   43 
##             아카데미               2023년                 내년 
##                   43                   42                   42 
##               복지부                   실   (주)디에스테크노와 
##                   42                   41                   40 
##                 12월               강진군                 소재 
##                   40                   40                   40 
##                 신입                 외국               음성군 
##                   40                   40                   40 
##             한양증권                 시험                  9급 
##                   33                   32                   30 
##                 건설                   결               공무원 
##                   30                   30                   30 
##                 공장                   급                 도입 
##                   30                   30                   30 
##               디지털             이차전지                 제주 
##                   30                   30                   30 
##                 청년               최고등             투자협약 
##                   30                   30                   30 
##                 내달             다빈치캠                 인턴 
##                   29                   28                   27 
##                   평               여주시       일자리드림데이 
##                   22                   21                   21 
##               1500억                  4번                  4회 
##                   20                   20                   20 
##                  7일                   것                 계절 
##                   20                   20                   20 
##           계절근로자               고용부                 공개 
##                   20                   20                   20 
##               공공형                 국어               근로제 
##                   20                   20                   20 
##                 기업                 남자                 네번 
##                   20                   20                   20 
##         다빈치캠퍼스                 대상                   등 
##                   20                   20                   20 
##               박람회                 번째               베트남 
##                   20                   20                   20 
##               새만금                   수               수원시 
##                   20                   20                   20 
##                 아내                 양성                   어 
##                   20                   20                   20 
##               은평구               이재명                 인재 
##                   20                   20                   20 
##               일자리                   접                   진 
##                   20                   20                   20 
##                   추             출제기조                   투 
##                   20                   20                   20 
##               해커톤                 객실               승무원 
##                   20                   19                   19 
##                   료                   성         의왕도시공사 
##                   18                   18                   17 
##               체험형                 신규                  3월 
##                   17                   16                   13 
##                   남                   내                 일정 
##                   12                   12                   12 
##             코딩능력                 표현               마지막 
##                   12                   12                   11 
##                    1                102명                 16조 
##                   10                   10                   10 
##                 17년            1조1600억               2024년 
##                   10                   10                   10 
##             2024전기               2025년                   27 
##                   10                   10                   10 
##                   29                   30                 35세 
##                   10                   10                   10 
##                 hds1               가능성                 가문 
##                   10                   10                   10 
##                 가치               간담회                   감 
##                   10                   10                   10 
##                 감소                 개선               개원식 
##                   10                   10                   10 
##                 개최                   거                 거부 
##                   10                   10                   10 
##                   경                 경영                 경쟁 
##                   10                   10                   10 
##             계약학과           고용노동부             고용불안 
##                   10                   10                   10 
##             고용창출             고용회복                 공격 
##                   10                   10                   10 
##                 공모               공모전                 공채 
##                   10                   10                   10 
##                 공포                 구인                 구직 
##                   10                   10                   10 
##               구직자                 구청                 국가 
##                   10                   10                   10 
##         국가필수선박               국산화         국제우호도시 
##                   10                   10                   10 
##                 규모     그랜드코리아레저             근로자용 
##                   10                   10                   10 
##             근로활동                 금단                   기 
##                   10                   10                   10 
##             기업잇는                   날                 남편 
##                   10                   10                   10 
##           노란봉투법       노인생활지원사           뉴스라이브 
##                   10                   10                   10 
##                 단독               단속반               대구시 
##                   10                   10                   10 
##               대규모                 돌풍                 동계 
##                   10                   10                   10 
##               동아대               디렉터           디스플레이 
##                   10                   10                   10 
##           디지털인재                   람                   마 
##                   10                   10                   10 
##                 명분               목표주               몸싸움 
##                   10                   10                   10 
##             문장가들                 문집             물류24시 
##                   10                   10                   10 
##             물리검층                 민간                 바다 
##                   10                   10                   10 
##                 박사               반도체                 반복 
##                   10                   10                   10 
##                   발               발전소                 방송 
##                   10                   10                   10 
##              방송3법             배토작업                   벌 
##                   10                   10                   10 
##                   변                 별거             보건난제 
##                   10                   10                   10 
## 보건의료고등연구계획             불법투기                   사 
##                   10                   10                   10 
##             사관학교                 사람                 사례 
##                   10                   10                   10 
##               사이버                   상               상당수 
##                   10                   10                   10 
##         상임감정위원             새만금에                   선 
##                   10                   10                   10 
##                   설                 성공             성본산단 
##                   10                   10                   10 
##               성황리                   세               세미나 
##                   10                   10                   10 
##                 수요             수요데이                 숙소 
##                   10                   10                   10 
##               시추공                 신당               신입생 
##                   10                   10                   10 
##             신입ᆞ경력                 신청                 실무 
##                   10                   10                   10 
##                   심                 심부                 심화 
##                   10                   10                   10 
##               쓰레기             아이디어           안드로이드 
##                   10                   10                   10 
##                 안전                   애             애정행각 
##                   10                   10                   10 
##                 양질         어르신일자리   어르신일자리박람회 
##                   10                   10                   10 
##                   없               엠오티                   연 
##                   10                   10                   10 
##                 연간                 영어        영어→현장직무 
##                   10                   10                   10 
##             영업이익                 영역                 오늘 
##                   10                   10                   10 
##               옥천군               온라인             외국인력 
##                   10                   10                   10 
##                 용납             우수기업                 원진 
##                   10                   10                   10 
##               유경준             유통업계                   은 
##                   10                   10                   10 
##     은평어르신일자리                   의   의료분쟁조정중재원 
##                   10                   10                   10 
##                   이               이낙연               이사회 
##                   10                   10                   10 
##             익산지청                 인식             인재양성 
##                   10                   10                   10 
##           일반대학원               입장문                 장비 
##                   10                   10                   10 
##               전문가               전주시                   제 
##                   10                   10                   10 
##               제조사                 조명                 종목 
##                   10                   10                   10 
##                   줄                   중                 중국 
##                   10                   10                   10 
##             중소기업                 중심                 증가 
##                   10                   10                   10 
##                 지역                 지연           지질자원연 
##                   10                   10                   10 
##                 진행                 참여                 채씨 
##                   10                   10                   10 
##                   첫                 체결               초고령 
##                   10                   10                   10 
##               최일수                 추가               추정치 
##                   10                   10                   10 
##               충북도                 취업             취업역량 
##                   10                   10                   10 
##                 칼바               케이프                 쾌커 
##                   10                   10                   10 
##               투자협             트렐릭스             패러다임 
##                   10                   10                   10 
##             패션비즈                 평강             풍힙현과 
##                   10                   10                   10 
##               플랜트               하츠타                 학생 
##                   10                   10                   10 
##             학술대회                   한    한국esg경영인증원 
##                   10                   10                   10 
##           한국교통대         한국철도공사               한양證 
##                   10                   10                   10 
##                 해결               해결사                   행 
##                   10                   10                   10 
##                 행사                   향           현대차그룹 
##                   10                   10                   10 
##               현직자                 혐오                 협약 
##                   10                   10                   10 
##             협의이혼                   호               화웨이 
##                   10                   10                   10 
##                   확                 확대                 활용 
##                   10                   10                   10 
##                 회복             훙멍시대                 희망 
##                   10                   10                   10 
##             희망퇴직                   尹               尹정부 
##                   10                   10                   10 
##                   外                  7대             강원교육 
##                   10                    9                    8 
##             도교육청               콜센터       고용촉진간담회 
##                    8                    8                    7 
##     충북북부보훈지청                   글               금융사 
##                    7                    6                    6 
##                   란                 모델             블라인드 
##                    6                    6                    6 
##         서린씨앤아이               시리즈               실무자 
##                    6                    6                    6 
##             에센코어                 여대                 용량 
##                    6                    6                    6 
##               크라스               클레브                  6기 
##                    6                    6                    5 
##       강원교육콜센터         강원도교육청     만트럭버스코리아 
##                    5                    5                    5 
##           아우스빌둥               출범식               기업들 
##                    5                    5                    4 
##               뒷조사                   래                 뭐길 
##                    4                    4                    4 
##                 사이               서비스                 유행 
##                    4                    4                    4 
##                 일본               취준생                    5 
##                    4                    4                    3 
##                 레벨             토론하자                e와글 
##                    3                    3                    2 
##                 광고             남성혐오                논란⋯ 
##                    2                    2                    2 
##             누리꾼들                   무                   속 
##                    2                    2                    2 
##                 영상                 유럽               포스코 
##                    2                    2                    2 
##           dn솔루션즈                 공략               독일에 
##                    1                    1                    1 
##                 센터                 시장             테크니컬 
##                    1                    1                    1 
##                   픈 
##                    1
hiring_date_freq<- hiring_date_pos2 %>%
  ungroup() %>% count(pos_done, sort=T) %>% rename(noun=pos_done)
hiring_date_freq

library(ggplot2)
## 
## Attaching package: 'ggplot2'
## The following object is masked from 'package:NLP':
## 
##     annotate
hiring_date_freq %>% ggplot(aes(x=noun, y=n)) +
  geom_bar(stat = "identity")

hiring_date_freq%>%slice_max(n,n=30)
hiring_date_freq%>%filter(n>=30)%>% ggplot(aes(x=noun, y=n)) +
  geom_bar(stat = "identity", aes(fill=n)) +
  theme(axis.text.x = element_text(angle = 90))

theme_set(theme_grey(base_family='NanumGothic'))

hiring_date_freq%>%filter(n>=30)%>% ggplot(aes(x=noun, y=n)) +
  geom_bar(stat = "identity", aes(fill=n)) +
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Well……?

What about this?

#install.packages("wordcloud2")
library(wordcloud2)

library(RColorBrewer)
display.brewer.all() 

library(wordcloud2)
wc_hiring_date<- wordcloud2(hiring_date_freq, fontFamily = "AppleGothic", 
           size=1,color = 'random-dark')
wc_hiring_date